package com.itheima.train.manager.service;

import com.alibaba.fastjson.JSON;
import com.itheima.train.manager.domain.SynSeatInfo;
import com.itheima.train.manager.domain.TbDicRidingPlan;
import com.itheima.train.manager.domain.TbDicTrainSeat;
import com.itheima.train.manager.domain.TbRidingPlanDate;
import com.itheima.train.manager.mapper.TbDicRidingPlanMapper;
import com.itheima.train.manager.mapper.TbDicTrainSeatMapper;
import com.itheima.train.manager.mapper.TbRidingPlanDateMapper;
import com.itheima.train.manager.mq.RabbitmqProducer;
import com.itheima.train.manager.utils.SnowFlakeGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
public class TbRidingPlanDateService {

    @Autowired(required = false)
    private TbRidingPlanDateMapper tbRidingPlanDateMapper ;

    @Autowired(required = false)
    private TbDicRidingPlanMapper tbDicRidingPlanMapper ;

    @Autowired(required = false)
    private TbDicTrainSeatMapper tbDicTrainSeatMapper ;

    @Autowired
    private RabbitmqProducer rabbitmqProducer ;

    // 创建一个雪花算法对象
    private final SnowFlakeGenerator snowFlakeGenerator = new SnowFlakeGenerator(0 , 0 ) ;

    // 创建一个线程池
    private ExecutorService executorService = Executors.newFixedThreadPool(10) ;

    // 生成指定日期的乘车计划数据
    public void genRidingPlanDate(String ridingDate) {

        // 1. 读取这个配置文件的车辆编号，然后遍历车辆编号集合，获取每一个车辆编号
        List<String> trainInfos = getTrainInfo(ridingDate) ;

        // 2. 根据车辆编号查询乘车计划数据
        executorService.submit(() -> {
            genRidingPlanDateString(trainInfos , ridingDate) ;
        }) ;


        // 3. 获取座位数据,然后将其发送到Rabbitmq中
        executorService.submit(() -> {
            synSeat(trainInfos , ridingDate) ;
        }) ;


    }

    private void synSeat(List<String> trainInfos, String ridingDate) {

        // 遍历trainInfos这个集合，获取每一个列车编号
        for(String trainInfo : trainInfos) {

            // 根据这个列车编号去查询其对应的座位数据
            List<TbDicTrainSeat> trainSeats = tbDicTrainSeatMapper.findByTrainNum(trainInfo);
            for(TbDicTrainSeat trainSeat : trainSeats) {

                executorService.submit(() -> {

                    // 构建我们要向mq中发送的数据对象
                    SynSeatInfo synSeatInfo = new SynSeatInfo() ;
                    BeanUtils.copyProperties(trainSeat , synSeatInfo);
                    synSeatInfo.setId(snowFlakeGenerator.nextId());
                    synSeatInfo.setStatus("0");
                    synSeatInfo.setDate(ridingDate);

                    // 发送同步数据
                    rabbitmqProducer.sendMessage(JSON.toJSONString(synSeatInfo) , "syn_seat");

//                    try {
//                        sendRdingPlanDateToLogstash(JSON.toJSONString(synSeatInfo));
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    }

                }) ;

            }

        }

    }

    private void genRidingPlanDateString(List<String> trainInfos, String ridingDate) {

        // 然后遍历车辆编号集合，获取每一个车辆编号
        for(String trainInfo : trainInfos) {
            List<TbDicRidingPlan> tbDicRidingPlans = tbDicRidingPlanMapper.findByTrainNum(trainInfo);
            for(TbDicRidingPlan tbDicRidingPlan : tbDicRidingPlans) {

                executorService.submit(() -> {

                    // 创建日期乘车计划对象
                    TbRidingPlanDate tbRidingPlanDate = new TbRidingPlanDate() ;
                    BeanUtils.copyProperties(tbDicRidingPlan , tbRidingPlanDate);
                    tbRidingPlanDate.setId(snowFlakeGenerator.nextId());

                    // 3. 添加上指定的乘车日期
                    tbRidingPlanDate.setTrainRidingDate(ridingDate);

                    // 4. 将其保存到数据库即可
                    tbRidingPlanDateMapper.save(tbRidingPlanDate);

                    // 发送指定日期的乘车计划数据到Rabbitmq中
                    rabbitmqProducer.sendMessage(JSON.toJSONString(tbRidingPlanDate) , "syn_riding_plan");
//                    try {
//                        sendRdingPlanDateToLogstash(tbRidingPlanDate);
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    }

                }) ;

            }
        }

    }

    // 推送数据到Logstash中
    public void sendRdingPlanDateToLogstash(Object obj) throws IOException {
        Socket socket = new Socket("127.0.0.1" , 5400) ;
        DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream()) ;
        System.out.println(JSON.toJSONString(obj));
        dataOutputStream.writeBytes(JSON.toJSONString(obj));
        dataOutputStream.flush();
        socket.close();
    }

    private List<String> getTrainInfo(String ridingDate) {

        // 创建一个List集合对象
        List<String> trainInfos = new ArrayList<>() ;

        // 获取配置文件所对应的流对象
        InputStream inputStream = null ;

        try{

            inputStream = TbRidingPlanDateService.class.getClassLoader().getResourceAsStream("train_info/train_info(" + ridingDate + ").info");
            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)) ;
            String line = null ;
            while((line = br.readLine()) != null) {
                trainInfos.add(line) ;
            }

        }catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        // 返回
        return trainInfos ;

    }

}
